#ifndef RP2BINDABLE_H
#define RP2BINDABLE_H

#include "Rp2System.h"
#include "Rp2Attributes.h"
#include "Rp2Renderer.h"

namespace Rp2
{
class ResourceIdentifier
{
public:
    // Abstract base class.  The destructor is *NOT* virtual so that the
    // derived-class destructors hide it.  This is intentional to avoid a
    // virtual function table pointer, a safe thing here because the base
    // class has no data.  This allows the derived classes that represent
    // vertex buffer information to store the input attributes first, and
    // allow typecasting of the following form.
    //
    //   class VBufferIdentifier : public ResourceIdentifier
    //   {
    //   public:  Attributes IAttr;
    //   }
    //   VBufferIdentifier* pkID = <some identifier>;
    //   Attributes& rkIAttr = *(Attributes*)pkID;

	~ResourceIdentifier() {/**/};

protected:
	ResourceIdentifier() {/**/};
};

class Bindable
{

public:
	Bindable();
	~Bindable();

    // Use this function when the resource has a unique representation in
    // VRAM (all resources except for vertex buffers).
	ResourceIdentifier* GetIdentifier (Renderer* pkUser) const;
	
    // Use these functions when the resource has multiple representations in
    // VRAM (vertex buffers).
	int GetInfoQuantity() const;
	int GetInfoQuantity(Renderer* pkUser) const;
	ResourceIdentifier* GetIdentifier(int i, Renderer* pkUser) const;

	void Release();

private:
	friend class Renderer;

	void OnLoad(Renderer* pkUser, Renderer::ReleaseFunction oRelease,
		ResourceIdentifier* pkID);
	
	void OnRelease(Renderer* pkUser, ResourceIdentifier* pkID);

	struct Info
	{
		// the renderer to which the resource is bound.
		Renderer* User;

		// the renderer function to call to release the resource
		Renderer::ReleaseFunction Release;

		// the identifier of the resource for the renderer's use.
		ResourceIdentifier* ID;
	};
	
	std::vector<Info> m_kInfoArray;
};

}

#endif